﻿using System;
using System.Collections.Generic;
using System.Web;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using Hxsoft.AppV1.Module;

namespace Hxsoft.AppV1._Controls
{
	[ValidationProperty("Value")]
	public partial class DicTreeSelector : Hxsoft.AppV1.UserControl
	{
		private LoadedValue<int?> loadedSiteId;
		public int? SiteId
		{
			get
			{
				if (loadedSiteId.Loader == null)
					loadedSiteId.Loader = () => (int?)ViewState["SiteId"];
				return loadedSiteId.Value;
			}
			set
			{
				if (loadedSiteId.Setter == null)
					loadedSiteId.Setter = v =>
						{
							loadedClassId.ResetValue();
							ViewState["SiteId"] = v;
						};
				loadedSiteId.Value = value;
			}
		}

		private LoadedValue<string> loadedClassCode;
		public string ClassCode
		{
			get
			{
				if (loadedClassCode.Loader == null)
					loadedClassCode.Loader = () => (string)ViewState["ClassCode"];
				return loadedClassCode.Value;
			}
			set
			{
				if (loadedClassCode.Setter == null)
					loadedClassCode.Setter = v => 
						{
							loadedClassId.ResetValue();
							ViewState["ClassCode"] = v;
						};
				loadedClassCode.Value = value;
			}
		}

		private LoadedValue<int> loadedClassId;
		protected int ClassId
		{
			get
			{
				if (loadedClassId.Loader == null)
					loadedClassId.Loader = () => { return DicClasses.GetIdentifier(SiteId, ClassCode).Value; };
				return loadedClassId.Value;
			}
		}

		public string Value
		{
			get
			{
				return CtrSelectorValue.Value;
			}
			set
			{
				CtrSelectorValue.Value = value;
			}
		}

		private LoadedValue<bool> loadedOnlySelectLeaf;
		public bool OnlySelectLeaf
		{
			get
			{
				if (loadedOnlySelectLeaf.Loader == null)
					loadedOnlySelectLeaf.Loader = () => BooleanExtensions.ConvertFromOrDefault(ViewState["OnlySelectLeaf"], false);
				return loadedOnlySelectLeaf.Value;
			}
			set
			{
				if (loadedOnlySelectLeaf.Setter == null)
					loadedOnlySelectLeaf.Setter = v => ViewState["OnlySelectLeaf"] = v;
				loadedOnlySelectLeaf.Value = value;
			}
		}

		private LoadedValue<int?> loadedPopupWidth;
		public int? PopupWidth
		{
			get
			{
				if (loadedPopupWidth.Loader == null)
					loadedPopupWidth.Loader = () => (int?)ViewState["PopupWidth"];
				return loadedPopupWidth.Value;
			}
			set
			{
				if (loadedPopupWidth.Setter == null)
					loadedPopupWidth.Setter = v => ViewState["PopupWidth"] = v;
				loadedPopupWidth.Value = value;
			}
		}

		private LoadedValue<int?> loadedPopupHeight;
		public int? PopupHeight
		{
			get
			{
				if (loadedPopupHeight.Loader == null)
					loadedPopupHeight.Loader = () => (int?)ViewState["PopupHeight"];
				return loadedPopupHeight.Value;
			}
			set
			{
				if (loadedPopupHeight.Setter == null)
					loadedPopupHeight.Setter = v => ViewState["PopupHeight"] = v;
				loadedPopupHeight.Value = value;
			}
		}

		private LoadedValue<bool> loadedIsStartLoadData;
		public bool IsStartLoadData
		{
			get
			{
				return CtrDicTree.Visible;
			}
			set
			{
				CtrDicTree.Visible = value;
			}
		}

		private LoadedValue<string> loadedSelectPromptTextItemSeparator;
		public string SelectPromptTextItemSeparator
		{
			get
			{
				if (loadedSelectPromptTextItemSeparator.Loader == null)
					loadedSelectPromptTextItemSeparator.Loader = () => StringExtensions.ConvertFromEffectiveValueOrDefault(ViewState["SelectPromptTextItemSeparator"], ",");
				return loadedSelectPromptTextItemSeparator.Value;
			}
			set
			{
				if (loadedSelectPromptTextItemSeparator.Setter == null)
					loadedSelectPromptTextItemSeparator.Setter = v => ViewState["SelectPromptTextItemSeparator"] = v;
				loadedSelectPromptTextItemSeparator.Value = value;
			}
		}

		private LoadedValue<DicValueType> loadedValueType;
		public DicValueType ValueType
		{
			get
			{
				if (loadedValueType.Loader == null)
					loadedValueType.Loader = () => EnumExtensions.ConvertFromOrDefault<DicValueType>(ViewState["ValueType"], DicValueType.DicId);
				return loadedValueType.Value;
			}
			set
			{
				if (loadedValueType.Setter == null)
					loadedValueType.Setter = v => ViewState["ValueType"] = v;
				loadedValueType.Value = value;
			}
		}

		protected override void OnPreRender(EventArgs e)
		{
			this.ApplicationPage.RegisterHeadIncludeFile(ApplicationConfiguration.JQueryUrl, IncludeFileType.JS);
			this.ApplicationPage.RegisterHeadIncludeFile(ApplicationConfiguration.CommonScriptUrl, IncludeFileType.JS);
			this.ApplicationPage.RegisterHeadIncludeFile(ApplicationConfiguration.DicTreeSelectorStyleUrl, IncludeFileType.CSS);

			if (PopupWidth.HasValue)
				CtrDicTree.Style.Add(HtmlTextWriterStyle.Width, PopupWidth.Value.ToString() + "px");
			if (PopupHeight.HasValue)
				CtrDicTree.Style.Add(HtmlTextWriterStyle.Height, PopupHeight.Value.ToString() + "px");

			ScriptManager.RegisterStartupScript(this, this.GetType(), this.ID + "_Init", "$(" + this.ClientID + "_Init);", true);

			base.OnPreRender(e);
		}

		protected override void Render(HtmlTextWriter writer)
		{
			switch (ValueType)
			{
				case DicValueType.Value:
					LoadSelectPromptTextByValue();
					break;
				default:
					LoadSelectPromptText();
					break;
			}

			base.Render(writer);
		}

		protected override void OnDataBinding(EventArgs e)
		{
			if (!IsStartLoadData) return;

			switch(ValueType)
			{
				case DicValueType.Value:
					BindDicTreeByValue(null);
					break;
				default:
					BindDicTree(null);
					break;
			}

			base.OnDataBinding(e);
		}

		protected void BindDicTree(TreeNode pNode)
		{
			int? pDicId = null;
			if (pNode != null)
				pDicId = int.Parse(pNode.Value);

			List<Dictionary> dics = Dictionaries.GetItems(ClassId, pDicId, true);

			string nodeNavText = null;
			if (dics.Count > 0)
			{
				Dictionary tDic = dics[0].Parent;
				while (tDic != null)
				{
					nodeNavText = tDic.Name + SelectPromptTextItemSeparator + nodeNavText;
					tDic = tDic.Parent;
				}
			}

			foreach (Dictionary dic in dics)
			{
				TreeNode node = new TreeNode(dic.Name, dic.DicId.ToString());
				node.SelectAction = TreeNodeSelectAction.None;
				node.PopulateOnDemand = dic.ChildCount > 0;

				if ((OnlySelectLeaf && dic.ChildCount == 0) || !OnlySelectLeaf)
				{
					node.SelectAction = TreeNodeSelectAction.Select;
					node.NavigateUrl = "javascript:" + this.ClientID + @"_SelectItem(""" + nodeNavText + node.Text + @""", """ + node.Value + @""");";
				}

				if (pNode != null)
					pNode.ChildNodes.Add(node);
				else
					CtrDicTree.Nodes.Add(node);
			}
		}

		protected void BindDicTreeByValue(TreeNode pNode)
		{
			string pValue = null;
			if (pNode != null)
				pValue = pNode.Value;

			List<Dictionary> dics = Dictionaries.GetItemsByParentValue(ClassId, pValue, true);

			string nodeNavText = null;
			if (dics.Count > 0)
			{
				Dictionary tDic = dics[0].Parent;
				while (tDic != null)
				{
					nodeNavText = tDic.Name + SelectPromptTextItemSeparator + nodeNavText;
					tDic = tDic.Parent;
				}
			}

			foreach (Dictionary dic in dics)
			{
				TreeNode node = new TreeNode(dic.Name, dic.Value);
				node.SelectAction = TreeNodeSelectAction.None;
				node.PopulateOnDemand = dic.ChildCount > 0;

				if ((OnlySelectLeaf && dic.ChildCount == 0) || !OnlySelectLeaf)
				{
					node.SelectAction = TreeNodeSelectAction.Select;
					node.NavigateUrl = "javascript:" + this.ClientID + @"_SelectItem(""" + nodeNavText + node.Text + @""", """ + node.Value + @""");";
				}

				if (pNode != null)
					pNode.ChildNodes.Add(node);
				else
					CtrDicTree.Nodes.Add(node);
			}
		}

		protected void LoadSelectPromptText()
		{
			CtrSelectorPromptText.ToolTip = Res.DicTreeSelector_SelectPromptText;

			string value = Value;
			if (string.IsNullOrEmpty(value))
			{
				CtrSelectorPromptText.Text = Res.DicTreeSelector_SelectPromptText;
				return;
			}

			int dicId = int.Parse(value);

			Dictionary dic = Dictionaries.GetItem(ClassId, dicId, true);
			if(dic == null)
			{
				CtrSelectorPromptText.Text = Res.DicTreeSelector_SelectPromptText;
				return;
			}

			string text = dic.Name;
			while (dic.Parent != null)
			{
				dic = dic.Parent;
				text = dic.Name + SelectPromptTextItemSeparator + dic.Name;
			}
			CtrSelectorPromptText.Text = text;
		}

		protected void LoadSelectPromptTextByValue()
		{
			CtrSelectorPromptText.ToolTip = Res.DicTreeSelector_SelectPromptText;

			string value = Value;
			if (string.IsNullOrEmpty(value))
			{
				CtrSelectorPromptText.Text = Res.DicTreeSelector_SelectPromptText;
				return;
			}

			Dictionary dic = Dictionaries.GetItemByValue(ClassId, value, true);
			if (dic == null)
			{
				CtrSelectorPromptText.Text = Res.DicTreeSelector_SelectPromptText;
				return;
			}

			string text = dic.Name;
			while (dic.Parent != null)
			{
				dic = dic.Parent;
				text = dic.Name + SelectPromptTextItemSeparator + dic.Name;
			}
			CtrSelectorPromptText.Text = text;
		}

		protected void CtrDicTree_TreeNodePopulate(object sender, TreeNodeEventArgs e)
		{
			switch (ValueType)
			{
				case DicValueType.Value:
					BindDicTreeByValue(e.Node);
					break;
				default:
					BindDicTree(e.Node);
					break;
			}
		}

		protected void CtrSelectorPromptText_Click(object sender, EventArgs e)
		{
			if (!IsStartLoadData)
			{
				IsStartLoadData = true;
				this.DataBind();
			}
		}
	}
}